/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "audio_command_handler.h"
#include "utils_log.h"
#include "file_manager.h"
#include "utils_string_ex.h"
#include "utils_crypto.h"
#include "utils_file_ex.h"
#include "media_speak.h"
#include "common_config_manager.h"
#include <chrono>
#include <iomanip>
#include <sstream>
#include <algorithm>

namespace El {
namespace Protocol {

void AudioCommandHandler::RegisterMethodHandlers(
    std::unordered_map<std::string, std::function<nlohmann::json(const std::string &, const nlohmann::json &)>>
        &handlers)
{
    // 注册音频文件上传方法
    handlers["audio.upload"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAudioUpload(id, params);
    };

    // 注册获取音频文件列表方法
    handlers["audio.getList"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAudioGetList(id, params);
    };

    // 注册播放音频文件方法
    handlers["audio.play"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAudioPlay(id, params);
    };

    // 注册停止音频播放方法
    handlers["audio.stop"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAudioStop(id, params);
    };

    // 注册删除音频文件方法
    handlers["audio.delete"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAudioDelete(id, params);
    };

    // 注册获取音频播放状态方法
    handlers["audio.getPlayStatus"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAudioGetPlayStatus(id, params);
    };

    // 注册获取正在播放的音频文件方法
    handlers["audio.getNowPlaying"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAudioGetNowPlaying(id, params);
    };

    // 注册下载音频文件方法
    handlers["audio.download"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAudioDownload(id, params);
    };

    // 注册获取扬声器配置方法
    handlers["speaker.getConfig"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleSpeakerGetConfig(id, params);
    };

    // 注册设置扬声器配置方法
    handlers["speaker.setConfig"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleSpeakerSetConfig(id, params);
    };

    // 注册获取音频输入设备列表方法
    handlers["audio.getInputDevices"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAudioGetInputDevices(id, params);
    };
}

nlohmann::json AudioCommandHandler::HandleAudioUpload(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理audio.upload请求, 参数: {}", params.dump());

    // 检查必要参数
    if (!params.contains("chunk_index") || !params["chunk_index"].is_number() || !params.contains("total_chunks") ||
        !params["total_chunks"].is_number() || !params.contains("chunk_data") || !params["chunk_data"].is_string()) {
        return CreateErrorResponse(id, 400, "缺少必要参数或参数格式不正确");
    }

    int chunkIndex = params["chunk_index"];
    int totalChunks = params["total_chunks"];
    std::string chunkData = params["chunk_data"];

    // 如果是第一个分块，创建新文件
    std::string fileId;
    if (chunkIndex == 0) {
        if (!params.contains("file_info") || !params["file_info"].is_object()) {
            return CreateErrorResponse(id, 400, "缺少文件信息或格式不正确");
        }

        const auto &fileInfo = params["file_info"];
        if (!fileInfo.contains("name") || !fileInfo.contains("size") || !fileInfo.contains("type")) {
            return CreateErrorResponse(id, 400, "文件信息不完整");
        }

        // 创建新文件
        fileId = FileManager::IFileManager::GetInstance().CreateFile(fileInfo["name"].get<std::string>(),
                                                                     FileManager::FileType::AUDIO);
        {
            std::lock_guard<std::mutex> lock(activeFilesMutex_);
            activeFiles_[id] = fileId;
        }

        if (fileId.empty()) {
            return CreateErrorResponse(id, 500, "创建文件失败");
        }
    } else {
        std::lock_guard<std::mutex> lock(activeFilesMutex_);
        if (activeFiles_.find(id) == activeFiles_.end()) {
            return CreateErrorResponse(id, 404, "找不到指定的音频文件");
        }
        fileId = activeFiles_[id];
    }

    // Base64解码数据
    std::vector<unsigned char> binaryData = El::Utils::Base64Decode(chunkData);
    std::string decodedData(binaryData.begin(), binaryData.end());

    // 写入文件块
    bool isLastBlock = (chunkIndex == totalChunks - 1);
    if (isLastBlock) {
        std::lock_guard<std::mutex> lock(activeFilesMutex_);
        activeFiles_.erase(id);
    }
    if (!FileManager::IFileManager::GetInstance().WriteFileBlock(fileId, decodedData, isLastBlock)) {
        return CreateErrorResponse(id, 500, "写入文件块失败");
    }

    // 计算上传进度
    int progress = static_cast<int>((chunkIndex + 1.0) / totalChunks * 100);

    nlohmann::json result = {{"status", "success"}, {"progress", progress}};
    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleAudioGetList(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理audio.getList请求, 参数: {}", params.dump());

    // 获取分页参数
    int page = params.value("page", 1);
    int pageSize = params.value("page_size", 20);

    // 获取音频文件列表
    auto fileList = FileManager::IFileManager::GetInstance().GetFileList(FileManager::FileType::AUDIO);

    // 分页
    int startIndex = (page - 1) * pageSize;
    int endIndex = std::min(startIndex + pageSize, static_cast<int>(fileList.size()));

    nlohmann::json audioFiles = nlohmann::json::array();
    for (int i = startIndex; i < endIndex; i++) {
        const auto &file = fileList[i];
        nlohmann::json audioFile = {{"id", file.id},     {"name", file.name}, {"size", file.size},
                                    {"type", file.type}, {"path", file.path}, {"last_access", file.last_access}};
        audioFiles.push_back(audioFile);
    }

    nlohmann::json result = {
        {"total", fileList.size()}, {"page", page}, {"page_size", pageSize}, {"audio_files", audioFiles}};

    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleAudioPlay(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理audio.play请求, 参数: {}", params.dump());

    // 检查必要参数
    if (!params.contains("audio_id") || !params["audio_id"].is_string()) {
        return CreateErrorResponse(id, 400, "缺少audio_id参数或格式不正确");
    }

    std::string audioId = params.value("audio_id", "");
    int32_t volume = params.value("volume", 80); // 默认音量80
    int32_t repeat = params.value("repeat", 1);  // 默认不重复播放

    // 获取文件信息
    FileManager::FileInfo fileInfo;
    if (!FileManager::IFileManager::GetInstance().GetFileInfo(audioId, fileInfo)) {
        return CreateErrorResponse(id, 404, "找不到指定的音频文件");
    }

    // 设置音量
    /*if (!Media::Speak::GetInstance().SetVolume(volume)) {
         return CreateErrorResponse(id, 500, "设置音量失败");
     }*/

    // 开始播放音频
    if (!Media::Speak::GetInstance().StartFilePlay(fileInfo.path.c_str(), repeat)) {
        return CreateErrorResponse(id, 500, "开始播放音频失败");
    }

    nlohmann::json result = {{"status", "success"}, {"audio_id", audioId}, {"name", fileInfo.name}, {"volume", volume}};

    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleAudioStop(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理audio.stop请求, 参数: {}", params.dump());

    // 获取播放任务ID（如果提供）
    std::string playId;
    if (params.contains("play_id") && params["play_id"].is_string()) {
        playId = params["play_id"].get<std::string>();
        EL_DEBUG("请求停止特定播放任务: {}", playId);
        // TODO: Speak类需要支持停止特定播放任务
        // 目前，无论是否提供play_id，都停止所有播放
    } else {
        EL_DEBUG("请求停止所有播放任务");
    }

    // 调用 Speak 停止播放
    Media::Speak::GetInstance().Stop();

    nlohmann::json result = {
        {"stopped_plays", nlohmann::json::array()} // TODO: 需要Speak类返回实际停止的任务ID
    };

    // 如果有play_id，则添加到响应中（假设成功停止了）
    if (!playId.empty()) {
        result["stopped_plays"].push_back(playId);
    }

    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleAudioDelete(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理audio.delete请求, 参数: {}", params.dump());

    // 检查必要参数
    if (!params.contains("audio_id") || !params["audio_id"].is_string()) {
        return CreateErrorResponse(id, 400, "缺少audio_id参数或格式不正确");
    }

    std::string audioId = params["audio_id"].get<std::string>();

    // 获取文件信息
    FileManager::FileInfo fileInfo;
    if (!FileManager::IFileManager::GetInstance().GetFileInfo(audioId, fileInfo)) {
        return CreateErrorResponse(id, 404, "找不到指定的音频文件");
    }

    // 删除文件
    if (!FileManager::IFileManager::GetInstance().DeleteFile(audioId)) {
        return CreateErrorResponse(id, 500, "删除文件失败");
    }

    nlohmann::json result = {{"id", audioId}, {"name", fileInfo.name}};

    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleAudioGetPlayStatus(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理audio.getPlayStatus请求, 参数: {}", params.dump());

    // TODO: 实现获取播放状态功能
    nlohmann::json result = {{"status", "not_implemented"}, {"message", "获取播放状态功能暂未实现"}};

    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleAudioGetNowPlaying(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理audio.getNowPlaying请求, 参数: {}", params.dump());

    std::string channel = "all";
    if (params.contains("channel") && params["channel"].is_string()) {
        channel = params["channel"].get<std::string>();
    }

    nlohmann::json playingFiles = nlohmann::json::array();

    // 获取当前播放的文件路径
    std::string filePath = Media::Speak::GetInstance().GetCurrentFilePath();
    if (!filePath.empty()) {
        std::string fileName = Utils::ExtractFileName(filePath);
        FileManager::FileInfo fileInfo;
        FileManager::IFileManager::GetInstance().GetFileInfoByName(fileName, fileInfo);

        // 构建单个音频文件播放信息
        nlohmann::json audioFile = {{"audio_id", fileInfo.id}};
        playingFiles.push_back(audioFile);
    }
    nlohmann::json result = {{"playing_files", playingFiles}};
    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleAudioDownload(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理audio.download请求, 参数: {}", params.dump());

    // 检查必要参数
    if (!params.contains("audio_id") || !params["audio_id"].is_string()) {
        return CreateErrorResponse(id, 400, "缺少audio_id参数或格式不正确");
    }

    std::string audioId = params["audio_id"].get<std::string>();
    int32_t chunkIndex = params.value("chunk_index", 0);
    int32_t chunkSize = params.value("chunk_size", 65536); // 默认64KB

    // 获取文件信息
    FileManager::FileInfo fileInfo;
    if (!FileManager::IFileManager::GetInstance().GetFileInfo(audioId, fileInfo)) {
        return CreateErrorResponse(id, 404, "找不到指定的音频文件");
    }

    // 计算总分块数
    int32_t totalChunks = (fileInfo.size + chunkSize - 1) / chunkSize;

    // 验证分块索引是否有效
    if (chunkIndex < 0 || chunkIndex >= totalChunks) {
        return CreateErrorResponse(id, 400, "无效的分块索引");
    }

    // 读取指定分块的数据
    std::string chunkData;
    if (!FileManager::IFileManager::GetInstance().ReadFileBlock(audioId, chunkIndex, chunkSize, chunkData)) {
        return CreateErrorResponse(id, 500, "读取文件分块失败");
    }

    // 对数据进行Base64编码
    std::vector<unsigned char> rawData(chunkData.begin(), chunkData.end());
    std::string base64Data = El::Utils::Base64Encode(rawData);

    // 构建响应
    nlohmann::json fileInfoJson = {{"name", fileInfo.name},
                                   {"size", fileInfo.size},
                                   {"type", fileInfo.type},
                                   {"total_chunks", totalChunks},
                                   {"current_chunk", chunkIndex}};

    nlohmann::json result = {{"status", "success"}, {"chunk_data", base64Data}, {"file_info", fileInfoJson}};

    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleSpeakerGetConfig(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理speaker.getConfig请求, 参数: {}", params.dump());

    int32_t volume = Media::Speak::GetInstance().GetVolume();
    // bool mute = false; // 静音功能暂未从 Media::Speak 获取，后续可添加 GetMute 方法
    // 实际项目中，你可能需要检查 Media::Speak 是否已初始化或 GetVolume 是否成功

    EL_INFO("获取到的扬声器音量: {}", volume);

    nlohmann::json result = {
        {"volume", volume},
        // {"mute", mute} // 暂时不包含静音状态，因为 Media::Speak::GetMute() 未实现
        // 根据协议文档，mute 字段是需要的，但当前 GetMute 未实现，暂时返回一个默认值或根据实际情况处理
        {"mute", false} // 暂时硬编码为 false，直到 GetMute 实现
    };

    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleSpeakerSetConfig(const std::string &id, const nlohmann::json &params)
{
    EL_DEBUG("处理speaker.setConfig请求, 参数: {}", params.dump());

    // 检查必要参数
    if (!params.contains("volume") || !params["volume"].is_number()) { // Mute is optional for now
        return CreateErrorResponse(id, 400, "缺少必要参数或参数格式不正确 (volume: number)");
    }

    int32_t volume = params["volume"].get<int32_t>();
    // bool mute = params.value("mute", false); // Mute is optional, default to false if not provided

    // 验证音量范围
    if (volume < 0 || volume > 100) {
        return CreateErrorResponse(id, 400, "音量参数无效，应在 0-100 之间");
    }

    EL_DEBUG("设置扬声器配置：音量 = {}", volume);

    // 设置音量和静音状态
    // 注意：这里假设 Media::Speak 提供了 SetVolume() 和 SetMute() 方法
    // if (Media::Speak::GetInstance().IsInitialized()) { // 假设有初始化检查
    if (!Media::Speak::GetInstance().SetVolume(volume)) {
        return CreateErrorResponse(id, 500, "设置音量失败");
    }
    //     if (!Media::Speak::GetInstance().SetMute(mute)) { // 静音功能暂时不实现
    //         return CreateErrorResponse(id, 500, "设置静音状态失败");
    //     }
    // } else {
    //     EL_ERROR("Media::Speak 未初始化，无法设置扬声器配置");
    //     return CreateErrorResponse(id, 500, "扬声器服务未准备好");
    // }

    nlohmann::json result = {
        {"status", "success"}, {"requires_reboot", false} // 根据实际情况确定是否需要重启
    };

    return CreateSuccessResponse(id, result);
}

nlohmann::json AudioCommandHandler::HandleAudioGetInputDevices(const std::string &id, const nlohmann::json &params)
{
    (void)params;  // 参数未使用,但接口需要
    EL_DEBUG("处理audio.getInputDevices请求");

    try {
        // 构建设备列表
        nlohmann::json deviceList = nlohmann::json::array();

        // 始终添加内置麦克风
        nlohmann::json builtinDevice = {
            {"id", "builtin"},
            {"name", "内置麦克风"},
            {"type", "builtin"},
            {"is_connected", true}
        };
        deviceList.push_back(builtinDevice);

        // 添加USB设备(硬件只有一个UAC设备)
        // 这里可以通过检查配置或事件来判断USB设备是否存在
        // 简化处理:始终显示USB选项,由底层判断是否可用
        nlohmann::json usbDevice = {
            {"id", "usb"},
            {"name", "USB麦克风"},
            {"type", "usb"},
            {"is_connected", false}  // 实际连接状态由底层peripheral模块管理
        };
        deviceList.push_back(usbDevice);

        nlohmann::json result = {
            {"devices", deviceList},
            {"total", deviceList.size()}
        };

        return CreateSuccessResponse(id, result);
    } catch (const std::exception& e) {
        EL_ERROR("获取音频输入设备列表失败: {}", e.what());
        return CreateErrorResponse(id, 500, "获取音频输入设备列表失败");
    }
}

} // namespace Protocol
} // namespace El